package com.lzm.toolfx.utils;

import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.image.Image;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import java.util.*;

/**
 * This class is JavaFx Alert Builder
 * Use example:
 * Optional<ButtonType> btn =  new DialogUtils(new DialogUtils.Builder()).showAndWait();
 *
 * @author LIANG
 * @since version 1.0 2020-11
 */
public class DialogUtils {

    private static Alert alert;
    private HBox contentPane;

    public DialogUtils(Builder builder) {
        alert = new Alert(builder.type);
        alert.setTitle(builder.title);
        Stage stage = (Stage) alert.getDialogPane().getScene().getWindow();
        if (builder.iconPath != null)
            stage.getIcons().add(new Image(builder.iconPath));
        else
            stage.getIcons().add(new Image(getIcoPath(builder.type)));
        alert.setHeaderText(builder.headerText);
        alert.setContentText(builder.content);
        if (builder.setButtonTypes.size() > 0) {
            alert.getButtonTypes().setAll(builder.setButtonTypes);
        }
        if (builder.addButtonTypes.size() > 0) {
            alert.getButtonTypes().addAll(builder.addButtonTypes);
        }
        if (builder.contentElements.size() > 0) {
            contentPane = new HBox();
            contentPane.setAlignment(Pos.TOP_RIGHT);
            contentPane.getChildren().setAll(builder.contentElements);
            alert.getDialogPane().setContent(contentPane);
        }
    }

    public Optional<ButtonType> showAndWait() {
        return alert.showAndWait();
    }

    public void show() {
        alert.show();
    }

    public HBox getContentPane() {
        return contentPane;
    }

    public Node getNode(Node node) {
        int index = contentPane.getChildren().indexOf(node);
        return contentPane.getChildren().get(index);
    }

    public Node getNode(String nodeId) {
        return contentPane.lookup(nodeId);
    }

    /**
     * Dialog Builder
     *
     * @author LIANG
     * @version 1.0 2020-11
     */
    public static class Builder {
        private String title;
        private String headerText;
        private String content;
        private String iconPath;
        private Alert.AlertType type;
        private List<ButtonType> setButtonTypes = new ArrayList<>();
        private List<ButtonType> addButtonTypes = new ArrayList<>();
        private List<Node> contentElements = new ArrayList<>();

        /**
         * This method allows you to set the Dialogs title Text
         *
         * @param title title
         */
        public Builder setTitle(String title) {
            this.title = title;
            return this;
        }

        /**
         * This method allows you to set the Dialogs content Text
         *
         * @param content content
         */
        public Builder setContent(String content) {
            this.content = content;
            return this;
        }

        /**
         * This method allows you to set the Dialogs header Text
         *
         * @param headerText headerText
         */
        public Builder setHeadText(String headerText) {
            this.headerText = headerText;
            return this;
        }

        /**
         * This method allows you to set the Dialogs iconPath to replace the default icons define by the Alert.AlertType
         *
         * @param iconPath iconPath
         */
        public Builder setIconPath(String iconPath) {
            this.iconPath = iconPath;
            return this;
        }

        /**
         * initialize the default icon by AlertType
         *
         * @param alertType alertType
         */
        public Builder setAlertType(Alert.AlertType alertType) {
            this.type = alertType;
            return this;
        }

        /**
         * set Dialog Buttons use List<ButtonType>
         * this will clear all default buttons
         *
         * @param buttonTypes buttonTypes
         */
        public Builder setButtonTypes(List<ButtonType> buttonTypes) {
            this.setButtonTypes = new ArrayList<>(buttonTypes);
            return this;
        }

        /**
         * set Dialog Buttons use ButtonType[]
         * this will clear all default buttons
         *
         * @param buttonTypes buttonTypes
         */
        public Builder setButtonTypes(ButtonType... buttonTypes) {
            this.setButtonTypes = new ArrayList<>(Arrays.asList(buttonTypes));
            return this;
        }

        /**
         * add Buttons to Dialog use List<ButtonType>
         * this will NOT clear default buttons
         *
         * @param buttonTypes buttonTypes
         */
        public Builder addButtonTypes(List<ButtonType> buttonTypes) {
            this.addButtonTypes = new ArrayList<>(buttonTypes);
            return this;
        }

        /**
         * add Buttons to Dialog use ButtonType[]
         * this will NOT clear default buttons
         *
         * @param buttonTypes buttonTypes
         */
        public Builder addButtonTypes(ButtonType... buttonTypes) {
            this.addButtonTypes = new ArrayList<>(Arrays.asList(buttonTypes));
            return this;
        }

        /**
         * set Dialog custom Node use List<Node>
         * this will clear all dialog's child
         *
         * @param contentElements contentElements
         */
        public Builder setContentElements(List<Node> contentElements) {
            this.contentElements = new ArrayList<>(contentElements);
            return this;
        }

        /**
         * set Dialog Buttons use Node[]
         * this will clear all dialog's child
         *
         * @param contentElements contentElements
         */
        public Builder setContentElements(Node... contentElements) {
            this.contentElements = new ArrayList<>(Arrays.asList(contentElements));
            return this;
        }
    }


    /**Set the Dialog's AlertType & ICON
     * if you want to change The default sets of icon img,YOU CAN
     *
     * @see Builder setIconPath()
     */
    private static String getIcoPath(Alert.AlertType type) {
        String path = "/static/img/dialog/dialog.png";
        String ALERT = "/static/img/dialog/alert.png";
        String INFORMATION = "/static/img/dialog/information.png";
        String CONFIRMATION = "/static/img/dialog/confirmation.png";
        String ERROR = "/static/img/dialog/error.png";
        switch (type) {
            case NONE:
                break;
            case WARNING:
                path = ALERT;
                break;
            case INFORMATION:
                path = INFORMATION;
                break;
            case ERROR:
                path = ERROR;
                break;
            case CONFIRMATION:
                path = CONFIRMATION;
                break;
        }
        return path;
    }
}
